import os.path
def main():
    while True:
        menu()
        choice=int(input('请选择功能菜单:'))
        if choice in [0,1,2,3,4,5,6,7]:
            if choice==0:
                answer=input('您确定要退出嘛？y/n')
                if answer=='y' or answer=='Y':
                    print('谢谢使用')
                    break    #退出系统
                else:
                    continue #退出该次询问
            elif choice == 1:
                insert()            # 录入
            elif choice == 2:
                search()            # 查询
            elif choice == 3:
                delete()            # 删除
            elif choice == 4:
                modify()            # 修改
            elif choice == 5:
                sort()              # 成绩排序
            elif choice == 6:
                total()             # 统计总人数
            elif choice == 7:
                show()              # 显示所有人信息

def menu():
    print('==================学生管理系统==================')
    print('-------------------功能菜单--------------------')
    print('\t\t\t\t1.录入学生信息')
    print('\t\t\t\t2.查找学生信息')
    print('\t\t\t\t3.删除学生信息')
    print('\t\t\t\t4.修改学生信息')
    print('\t\t\t\t5.成绩排序')
    print('\t\t\t\t6.统计学生总人数')
    print('\t\t\t\t7.显示所有学生信息')
    print('\t\t\t\t0.退出')
    print('-------------------功能菜单--------------------')

def insert():
    student_list=[]   #创建一个空列表用于存储录入的学生信息的字典，列表中的元素是一个个字典
    while True:       #循环去录入学生信息
        Id=input('请输入学生ID(如1001):')
        if Id=='':    #手抖输入的是空，空字符串的bool值是false，not false就是true，则没有录入的情况下直接break跳出插入函数
            break
        name=input('请输入姓名：')
        if not name:
            break
        #如果录入的不是空字符串就继续录入成绩（但是录入成绩时，也可能有输入错误），所以运用 try except
        try:
            english=int(input("请输入英语成绩："))
            python=int(input("请输入python成绩："))
            java=int(input("请输入java成绩："))
        except:
            print('输入无效，不是整数类型吗，请重新输入')
            continue #结束这次循环，进入下一次循环，重新输入ID

        #将录入的学生信息保存在名叫student_dict的字典当中key_value,我们录入的都是value
        student_dict={ 'ID':Id,'Name':name,'English':english,'Python':python,'Java':java  }
        #将学生信息添加到列表当中
        student_list.append(student_dict)
        answer=input('是否继续添加？y/n')
        if answer=='y':
            continue
        else:
            break
    #调用写好的save()函数,参数是列表，将列表中的信息写入文件student.txt
    save(student_list)
    print('学生信息录入完毕！')

def save(lst):
    try:
        file=open('student_txt','a',encoding='utf_8')   #打开student_txt文件，如果不存在，自动创建追加
    except:
        file=open('student_txt','w',encoding='utf_8')
    for item in lst:
        file.write(str(item)+'\n')
    file.close()



def search():
    student_query = []
    while True:
        Id=''   #这是输入的值value，不是键key
        name=''
        if os.path.exists('student_txt'):
            mode=input('按ID查找请输入1，按姓名查找请输入2: ')
            if mode=='1':

                Id=input('请输入学生ID')
            elif mode=='2':
                name=input('请输入学生姓名:')
            else:
                print('您的输入有误，请重新输入')
                search()
            with open('student_txt','r',encoding='utf-8') as rfile:
                student=rfile.readlines()
                for item in student:
                    d=dict(eval(item))
                    if Id!='':
                        if d['ID'] == Id:
                            student_query.append(d)
                    elif name != '':
                        if d['Name']==name :
                            student_query.append(d)
            # 显示查询结果
            show_student(student_query)
            # 清空列表
            student_query.clear()
            answer=input('是否要继续查询?y/n\n')
            if answer =='y':
                continue
            else:
                break
        else:
            print('暂未保存学生信息')
            return

def delete():
    while True:
        delete_id=input('请输入你要删除的学生的Id：')
        if delete_id !='':
            if os.path.exists('student_txt'): #如果存在student_text这个文本，就已读取的形式打开它
                with open('student_txt','r',encoding='utf-8') as file:
                    '''readlines()将文本中的每一行的内容当作一个字符串对象，并返回到一个列表中，这个列表起名old_chart'''
                    old_chart=file.readlines()
            else:#路径不存在，创建一个空列表
                old_chart=[]

            flag=False #用于标记是否删除

            if old_chart:  #如果列表不是空的，而是完成将读到的内容赋给了它,则只以写的方式打开，（会覆盖）
                with open('student_txt','w',encoding='utf_8') as wfile: #准备重写这个文本
                    d={}  #创建一个空字典
                    # 遍历已读入完成的列表old_chart,每一个元素都是一个字符串
                    # 将字符串转成字典，以便后面根据key检索到值value和输入的delete_id,做个对比
                    for item in old_chart:
                        d=dict(eval(item))
                        if d['ID']== delete_id: #如果一样就舍弃不再写入，并表示找到了要删除的对象，将标志调为找到
                            flag = True
                        else:#如果挨个检索的id不是要删除的id就将它重新写入文本student.txt
                            wfile.write(str(d)+'\n')
                    if flag:
                        print(f"ID为"+str(delete_id)+"的学生信息已被删除")
                    else:
                        print('没有找到ID为'+str(delete_id)+'的学生信息')
            # 列表是空的，说明文本student_txt,压根不存在
            else:
                print('无学生存储信息表')
                break
            answer=input('是否继续删除？y/n')
            if answer=='y':
                continue
            else:
                break
            # show() #删除之后要重新显示所有学生信息

def modify():
    show()
    if os.path.exists('student_txt'):
        with open('student_txt','r', encoding='utf-8') as rfile:
            old_chart=rfile.readlines()
    else:
        return
    student_id = input('请输入要修改的学员的ID:')
    with open('student_txt','w',encoding='utf-8') as wfile:
        for item in old_chart:
            d=dict(eval(item))
        if d['ID'] == student_id:
            print('找到学生信息，可以修改他的相关信息了!')
            while True:
                try:
                    d['Name'] = input('请输入姓名:')
                    d['English'] = int(input('请输入英语成绩:'))
                    d['Python'] = int(input('请输入Python成绩:'))
                    d['Java'] = int(input('请输入Java成绩:'))
                except:
                    print('您的输入有误，请重新输入!!!')
                else:
                    break #跳出while True的无线循环
            wfile.write(str(d)+'\n') #将修改后的字典的内容以字符串的形式写入文本
            print('修改成功!!!')
        else:
            print('没有找到对应学生信息')
            wfile.write(str(d) + '\n')  # id不相等，因为一w只写方式打开会覆盖，也要把原来遍历的全部写回去

    answer = input('是否继续修改其它学生信息?y/n\n')
    if answer=='y':
        modify()
    else:
        return


def sort():
    show()
    if os.path.exists('student_txt '):
        with open('student_txt' , 'r', encoding='utf-8') as rfile:
            student_list = rfile.readlines()  #studen_list是用来存放readlines函数返回值的列表
        student_new = []
        for item in student_list:
            d = dict(eval(item))
        student_new.append(d)
    else:
        return
    asc_or_desc = input('请选择(0:升序 1:降序):')
    if asc_or_desc == '0':
        asc_or_desc_bool = False #False 用来标志准备升序排序
    elif asc_or_desc == '1':
        asc_or_desc_bool = True  #True  用来标志准备降序排序
    else:
        print('您的输入有误，请重新输入')
        sort()
    mode = input('请选择排序方式(1:按英语成绩排序 2:按Python成绩排序 3:按Java成绩排序 0:按总成绩排序):')
    if mode == '1':
        student_new.sort(key=lambda x: int(x['English']), reverse = asc_or_desc_bool)
    elif mode == '2':
        student_new.sort(key=lambda x: int(x['Python']), reverse = asc_or_desc_bool)
    elif mode == '3':
        student_new.sort(key=lambda x: int(x['Java']) ,reverse = asc_or_desc_bool)
    elif mode == 'O':
        student_new.sort(key=lambda x: int(x['English'])+int(x['Python'])+int(x['Java']),reverse = asc_or_desc_bool)
    else:
        print('您的输入有误，请重新输入!!!')
        sort()
    show_student(student_new)


def total():
    if os.path.exists('student_txt '):# 判断文件是否存在
        with open('student_txt ', 'r', encoding='utf-8') as rfile:  # 打开文件
            students = rfile.readlines()  # 读取全部内容
        if students:
            print('一共有{}名学生。'.format(len(students)))  #一行一个人
        else:
             print('还没有录入学生信息。')
    else:
        print('暂未保存数据信息...')

def show():
    student_lst=[]
    if os.path.exists('student_txt'):
        with open('student_txt','r',encoding='utf_8') as rfile:
            students=rfile.readlines()   #因为文本中原来每一行存的是都是一个字典，被readlines()以后变成了字符串字典，存在一个大列表中
            for item in students:     #遍历这个大列表，item是一个个字符串字典 "{ 'ID':xx,'Name':xx,'English':xx,'Python':xx,'Java':xx }"
                student_lst.append(eval(item)) #  eval(item)的结果是dict，添加在列表student_lst的结尾
        if student_lst:
            show_student(student_lst)
            # student_lst.clear()

# student_lst 变成下面的形式
#[ {'ID':xx,'Name':xx,'English':xx,'Python':xx,'Java':xx}, {'ID':xx,'Name':xx,'English':xx,'Python':xx,'Java':xx} , {'ID':xx,'Name':xx,'English':xx,'Python':xx,'Java':xx}, ... ]

def show_student(lst):
    if len(lst)==0:
        print('没有查询到学生信息，无数据显示!!!')
        return
    # 定义标题显示格式
    format_title='{:^6}\t{:^12}\t{:^8}\t{:^10}\t{:^10}\t{:^8}'
    print(format_title.format('ID','姓名','英语成绩','Python成绩','Java成绩','总成绩'))
    # 定义内容的显示格式
    format_data ='{:^6}\t{:^12}\t{:^10}\t{:^10}\t{:^10}\t{:^10}'
    for item in lst:  # [ {'ID':xx,'Name':xx,'English':xx,'Python':xx,'Java':xx},{'ID':xx,'Name':xx,..}.. ]
        print(format_data.format( item.get('ID'),
                                  item.get('Name'),
                                  item.get('English'),
                                  item.get('Python'),
                                  item.get('Java'),
                                  int(item.get('English')) + int(item.get('Python')) + int(item.get('Java'))
                                  ))




'''上面把所有函数都定义好后，要以主程序的方式调用'''
if __name__=='__main__':      #不加这句话话程序运行时什么都没有
    main()




